use rust_decimal::Decimal;

#[derive(Debug, PartialEq, Copy, Clone)]
pub enum Token {
   Add,
   Subtract,
   Multiply,
   Divide,
   Caret,
   LeftParen,
   RightParen,
   Number(Decimal),
   Eof,
}

#[derive(Debug, PartialEq, PartialOrd, Copy, Clone)]
pub enum OperatorPrecedence {
   Default,          // 0
   AddOrSubtract,    // 1
   MultiplyOrDivide, // 2
   Power,            // 3
   Negative,         // 4
}

impl std::fmt::Display for Token {
   fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
      use Token::*;
      match self {
         Add => write!(f, "+"),
         Subtract => write!(f, "-"),
         Multiply => write!(f, "*"),
         Divide => write!(f, "/"),
         Caret => write!(f, "^"),
         LeftParen => write!(f, "("),
         RightParen => write!(f, ")"),
         Number(num) => write!(f, "{num}"),
         Eof => write!(f, "Eof"),
      }
   }
}

impl Token {
   pub fn get_precedence(&self) -> OperatorPrecedence {
      use OperatorPrecedence::*;
      use Token::*;

      match self {
         Add | Subtract => AddOrSubtract,
         Multiply | Divide => MultiplyOrDivide,
         Caret => Power,
         _ => Default,
      }
   }
}
